<template>
    <div class="potatoflow">
        <div class="operationPanel">
            <div class="nodeType">
                <div v-for="(data, type) in nodeTypeData" :key="type" class="nodeTypeItem">
                    <div :class="type" @mousedown="addNode(type)">
                        <svg v-if="type == 'line'">
                            <line x1="0" y1="0" x2="50" y2="30" style="stroke:#000;stroke-width:1"/>
                        </svg>
                    </div>
                </div>
            </div>
        </div>
        <svg class="potatoflowDraw" @mousemove="mouseMove()" @mouseup="drawMouseup" @mouseover="mouseover" @mouseout="mouseout">
            <defs>
            <marker id='markerArrow' markerWidth='18' markerHeight='10' refX="10" refY="6" orient='auto'>
                <path d='M2,2 L10,6 L2,10 L2,2' style='fill:#000;stroke-width:2'/>
            </marker>
            </defs>
            <g v-for="(node, index) in nodeList" :key="node" @mousedown="mousedown(index)" @mouseenter="nodeMouseenter(node)" @mouseleave="nodeMouseleave(node)" class="nodeItem">
                <rect
                    v-if="node.type == 'rect'"
                    :x = "node.x"
                    :y = "node.y"
                    :width = "node.width"
                    :height = "node.height"
                    :style = "node.style"
                />
                <circle
                    v-if="node.type == 'circle'"
                    :cx = "node.x"
                    :cy = "node.y"
                    :r = "node.r"
                    :style = "node.style"
                />
                <line
                    v-if="node.type == 'line'"
                    :x1 = "node.x1"
                    :y1 = "node.y1"
                    :x2 = "node.x2"
                    :y2 = "node.y2"
                    :style = "node.style"
                    marker-end="url(#markerArrow)"
                />
                <!-- 定位点 -->
                <circle v-for="(positionNode) in node.positionNodeList" :key="positionNode" @mouseup="positionNodeMouseup"
                    @mousedown="positionNodeMousedown(node, positionNode, index)"
                    @mouseenter="positionNodeMouseenter(node, positionNode)"
                    @mouseleave="positionNodeMouseleave(node, positionNode)"
                    :cx = "positionNode.x"
                    :cy = "positionNode.y"
                    r = "4"
                    stroke="#000"
                    troke-width="1"
                    fill="#fff"
                    :style = "positionNode.style"
                />
            </g>
        </svg>
    </div>
</template>
    
<script>
export default {
    name: "MyPotatoflow",
    data() {
        return {
            // 节点集合
            nodeList: [],
            nodeMap: {},
            // 操作的节点临时对象
            nodeTemp: null,
            // 要添加的节点临时对象
            addNodeTemp: null,
            // 节点类型集合
            nodeTypeData: {
                "rect": {

                },
                "circle": {
                    
                },
                "line": {

                }
            },
            nodeTypeInfo: {
                
            },
            // 定位坐标使用的节点--鼠标移动到节点上，显示的边界点和中心点
            positionNodeList: [],
            // 临时鼠标位置记录
            eventTemp: [],
            // 定位点记录
            positionNodeTemp: null
        }
    },
    mounted() {
        // this.init();
    },
    methods: {
        init() {
            var _this = this;
            // alert();
            let node1 = {};
            node1.type = "rect";
            node1.x = 100;
            node1.y = 0;
            node1.width = 100;
            node1.height = 50;
            node1.style = {
                fill: "#fff",
                strokeWidth: "1",
                stroke: "rgb(0, 0, 0)"
            };
            _this.nodeList.push(node1);
        },
        /**
         * 鼠标移动事件
         */
        mouseMove() {
            let _this = this;
            // 有正在操作的节点
            if (_this.nodeTemp != null) {
                console.log("----------------");
                var node = _this.nodeList[_this.nodeTemp.index];
                switch(node.type) {
                    case 'line':
                        // 正在编辑的节点
                        if (node.loading) {
                            if (node.loadingType == "start") {
                                // 正在绘制的直线，起点为鼠标位置
                                if (_this.nodeList[_this.nodeList.length - 1].x2 > event.pageX) {
                                    _this.nodeList[_this.nodeList.length - 1].x1 = event.pageX+1;
                                    _this.nodeList[_this.nodeList.length - 1].y1 = event.pageY+1;
                                } else {
                                    _this.nodeList[_this.nodeList.length - 1].x1 = event.pageX-1;
                                    _this.nodeList[_this.nodeList.length - 1].y1 = event.pageY-1;
                                }
                                
                            } else {
                                // 正在绘制的直线，终点为鼠标位置
                                if (_this.nodeList[_this.nodeList.length - 1].x1 > event.pageX) {
                                    _this.nodeList[_this.nodeList.length - 1].x2 = event.pageX+1;
                                    _this.nodeList[_this.nodeList.length - 1].y2 = event.pageY+1;
                                } else {
                                    _this.nodeList[_this.nodeList.length - 1].x2 = event.pageX-1;
                                    _this.nodeList[_this.nodeList.length - 1].y2 = event.pageY-1;
                                }
                            }
                        }
                        break;
                    default:
                        node.x = _this.nodeTemp.x + event.pageX - _this.nodeTemp.eventXTemp;
                        node.y = _this.nodeTemp.y + event.pageY - _this.nodeTemp.eventYTemp;
                        _this.nodeMouseenter(node);
                        // 移动直线
                        for (var i = 0; i < _this.nodeList.length; i++) {
                            if (_this.nodeList[i].type == 'line') {
                                if (_this.nodeList[i].start == node.id) {
                                    _this.nodeList[i].x1 = node.x;
                                    _this.nodeList[i].y1 = node.y;
                                } else if (_this.nodeList[i].end == node.id) {
                                    _this.nodeList[i].x2 = node.x;
                                    _this.nodeList[i].y2 = node.y;
                                }
                            }
                        }
                        break;
                }
            }
        },
        /**
         * 节点鼠标按下事件，开始操作节点
         */
        mousedown(index) {
            let _this = this;
            // 如果有节点正在操作，则当前节点不进行操作
            if (_this.nodeTemp == null) {
                // 将当前元素移动至最后一个，使其在图形最上层
                _this.nodeList.push(_this.nodeList[index]);
                _this.nodeList.splice(index, 1);
                var indexNew = _this.nodeList.length - 1;
                // 设置临时节点
                _this.setNodeTemp(indexNew);
            }
        },
        /**
         * 设置临时节点
         */
        setNodeTemp(indexNew) {
            let _this = this;
            _this.nodeTemp = JSON.parse(JSON.stringify(_this.nodeList[indexNew]));
            _this.nodeTemp.index = indexNew;
            switch(_this.nodeTemp.type) {
                case 'rect':
                    if (_this.nodeTemp.temp) {
                        _this.nodeTemp.eventXTemp = _this.nodeTemp.width/2;
                        _this.nodeTemp.eventYTemp = _this.nodeTemp.height/2;
                    } else {
                        _this.nodeTemp.eventXTemp = event.pageX;
                        _this.nodeTemp.eventYTemp = event.pageY;
                    }
                    break;
                case 'circle':
                    if (_this.nodeTemp.temp) {
                        _this.nodeTemp.eventXTemp = 0;
                        _this.nodeTemp.eventYTemp = 0;
                    } else {
                        _this.nodeTemp.eventXTemp = event.pageX;
                        _this.nodeTemp.eventYTemp = event.pageY;
                    }
                    break;
                case 'line':
                    break;
                default:
                    break;
            }
        },
        /**
         * 添加节点
         */
        addNode(nodeType) {
            let _this = this;
            var addNodeTemp = {};
            addNodeTemp.id = new Date().getTime();
            switch(nodeType) {
                case 'rect':
                    addNodeTemp.type = "rect";
                    addNodeTemp.x = 0;
                    addNodeTemp.y = 0;
                    addNodeTemp.width = 100;
                    addNodeTemp.height = 50;
                    addNodeTemp.style = {
                        fill: "#fff",
                        strokeWidth: "2",
                        stroke: "rgb(0, 0, 0)",
                        display: "none"
                    };
                    addNodeTemp.temp = true;
                    _this.nodeList.push(addNodeTemp);
                    break;
                case 'circle':
                    addNodeTemp.type = "circle";
                    addNodeTemp.x = 0;
                    addNodeTemp.y = 0;
                    addNodeTemp.r = 25;
                    addNodeTemp.style = {
                        fill: "#fff",
                        strokeWidth: "2",
                        stroke: "rgb(0, 0, 0)",
                        display: "none"
                    };
                    addNodeTemp.temp = true;
                    _this.nodeList.push(addNodeTemp);
                    break;
                case 'line':
                    addNodeTemp.type = "line";
                    addNodeTemp.style = {
                        strokeWidth: "1",
                        stroke: "rgb(0, 0, 0)",
                        display: "none"
                    };
                    addNodeTemp.temp = true;
                    _this.nodeList.push(addNodeTemp);
                    break;
                default:
                    break;
            }
            // 设置临时节点
            _this.setNodeTemp(_this.nodeList.length - 1);
            _this.nodeMap[addNodeTemp.id, addNodeTemp];
            console.log(_this.nodeList);
        },
        /**
         * 定位点鼠标释放
         */
        positionNodeMouseup() {
            let _this = this;
            // 正在操作的节点
            if (_this.nodeTemp != null) {
                // _this.nodeList[_this.nodeTemp.index].loading = false;
                // _this.nodeTemp = null;
            }
        },
        /**
         * 画布鼠标释放事件
         */
        drawMouseup() {
            let _this = this;
            // 正在操作的节点
            if (_this.nodeTemp != null) {
                var node = _this.nodeList[_this.nodeTemp.index];
                switch(node.type) {
                    case 'line':
                        // 直线绘制过程中
                        if (node.loading) {
                            // 指向了定位点
                            if (_this.positionNodeTemp != null) {
                                // 起点
                                if (node.loadingType == 'start') {
                                    node.x1 = _this.positionNodeTemp.x;
                                    node.y1 = _this.positionNodeTemp.y;
                                // 终点
                                } else {
                                    node.x2 = _this.positionNodeTemp.x;
                                    node.y2 = _this.positionNodeTemp.y;
                                }
                                // 指定节点属性
                                node[node.loadingType] = _this.positionNodeTemp.id;
                            } else {
                                node[node.loadingType] = null;
                            }
                            _this.nodeList[_this.nodeList.length - 1].loading = false;
                            _this.nodeList[_this.nodeList.length - 1].temp = false;
                            _this.nodeTemp = null;
                        // 直线还未创建
                        } else if (node.temp) {
                            // 设置起点
                            // 指向了定位点
                            if (_this.positionNodeTemp != null) {
                                node.x1 = _this.positionNodeTemp.x;
                                node.y1 = _this.positionNodeTemp.y;
                                node.x2 = _this.positionNodeTemp.x;
                                node.y2 = _this.positionNodeTemp.y;
                            // 未指向定位点
                            } else {
                                node.x1 = event.pageX;
                                node.y1 = event.pageY;
                                node.x2 = event.pageX;
                                node.y2 = event.pageY;
                            }
                            // 显示直线，设置节点为正在绘制中
                            node.loading = true;
                            node.loadingType = 'end';
                            node.temp = false;
                            node.style.display = "block";
                        }
                        _this.positionNodeTemp = null;
                        break;
                    default:
                        node.temp = false;
                        _this.nodeTemp = null;
                        break;
                }
            }
        },
        /**
         * 画布鼠标移入事件
         */
        mouseover() {
            let _this = this;
            // 有需要新增的节点，并且节点已加载完成
            if (_this.nodeList.length > 0 && _this.nodeList[_this.nodeList.length - 1].temp && !_this.nodeList[_this.nodeList.length - 1].loading) {
                _this.nodeList[_this.nodeList.length - 1].style.display = "block";
            }
        },
        /**
         * 画布鼠标移出事件
         */
        mouseout() {
            let _this = this;
            // 有需要新增的节点，并且节点已加载完成
            if (_this.nodeList.length > 0 && _this.nodeList[_this.nodeList.length - 1].temp && !_this.nodeList[_this.nodeList.length - 1].loading) {
                _this.nodeList[_this.nodeList.length - 1].style.display = "none";
            }
        },
        /**
         * 节点鼠标移入事件
         */
        nodeMouseenter(node) {
            if (node.temp || node.loading) {
                return;
            }
            let _this = this;
            node.positionNodeList = [];
            switch(node.type) {
                // 矩形
                case 'rect':
                    // 中心点
                    var center = {"x": node.x + node.width/2, "y": node.y + node.height/2};
                    // 上左
                    var topleft = {"x": node.x, "y": node.y};
                    // 上中
                    var top = {"x": node.x + node.width/2, "y": node.y};
                    // 上右
                    var topright = {"x": node.x + node.width, "y": node.y};
                    // 左中
                    var left = {"x": node.x, "y": node.y + node.height/2};
                    // 右中
                    var right = {"x": node.x + node.width, "y": node.y + node.height/2};
                    // 下左
                    var bottomleft = {"x": node.x, "y": node.y + node.height};
                    // 下中
                    var bottom = {"x": node.x + node.width/2, "y": node.y + node.height};
                    // 下右
                    var bottomright = {"x": node.x + node.width, "y": node.y + node.height};
                    // 添加节点
                    node.positionNodeList = [center, topleft, top, topright, left, right, bottomleft, bottom, bottomright];
                    break;
                // 圆
                case 'circle':
                    // 中心点
                    var center = {"x": node.x , "y": node.y};
                    // 上
                    var top = {"x": node.x, "y": node.y - node.r};
                    // 左
                    var left = {"x": node.x - node.r, "y": node.y};
                    // 右
                    var right = {"x": node.x + node.r, "y": node.y};
                    // 下
                    var bottom = {"x": node.x, "y": node.y + node.r};
                    // 添加节点
                    node.positionNodeList = [center, top, left, right, bottom];
                    break;
                // 直线
                case 'line':
                    // 起点
                    var start = {"x": node.x1 , "y": node.y1, "type": "start"};
                    // 终点
                    var end = {"x": node.x2, "y": node.y2, "type": "end"};
                    node.positionNodeList = [start, end];
                    break;
                default:
                    break;
            }
            // 记录当前临时鼠标位置
            _this.eventTemp = [event.pageX, event.pageY];
        },
        /**
         * 节点鼠标移出事件
         */
        nodeMouseleave(node) {
            let _this = this;
            // 鼠标未发生移动时，不删除定位点
            if (_this.eventTemp != [event.pageX, event.pageY]) {
                node.positionNodeList = [];
            }

            
        },
        /**
         * 定位点鼠标按下事件
         */
        positionNodeMousedown(node, positionNode, index) {
            let _this = this;
            // 如果有节点正在操作，则当前节点不进行操作
            if (_this.nodeTemp == null) {
                switch(node.type) {
                    case 'line':
                        node.loading = true;
                        node.loadingType = positionNode.type;
                        // 将当前元素移动至最后一个，使其在图形最上层
                        _this.nodeList.push(_this.nodeList[index]);
                        _this.nodeList.splice(index, 1);
                        let indexNew = _this.nodeList.length - 1;
                        _this.nodeTemp = JSON.parse(JSON.stringify(_this.nodeList[indexNew]));
                        _this.nodeTemp.index = indexNew;
                        break;
                    default:
                        
                        break;
                }
            }
            
        },
        /**
         * 定位点鼠标移入事件
         */
        positionNodeMouseenter(node, positionNode) {
            let _this = this;
            positionNode.style = {
                stroke: "#ff0000"
            };
            switch(node.type) {
                case 'line':
                    break;
                default:
                    _this.positionNodeTemp = positionNode;
                    _this.positionNodeTemp.id = node.id;
                    break;
            }
        },
        /**
         * 定位点鼠标移出事件
         */
        positionNodeMouseleave(node, positionNode) {
            let _this = this;
            positionNode.style = {
                stroke: "#000"
            };
            _this.positionNodeTemp = null;
        }
    },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
#app, .potatoflow, .potatoflowDraw {
    height: 100%;
}
.potatoflow {
    position: relative;
}
.potatoflowDraw {
    width: 100%;
}
.operationPanel {
    position: absolute;
    width: 120px;
    height: 100%;
    padding: 10px;
    box-sizing: border-box;
}
.nodeType {
    height: 100%;
    background-color: #fff;
    border: 1px solid #000;
    box-sizing: border-box;
}
.nodeTypeItem {
    height: 50px;
}
.nodeItem {
    cursor: pointer;
}
/* 节点类型样式 */
.rect {
    margin: 0 auto;
    width: 50px;
    height: 30px;
    border: 1px solid #000;
    position: relative;
    top: 10px;
}
.circle {
    margin: 0 auto;
    width: 30px;
    height: 30px;
    border: 1px solid #000;
    position: relative;
    top: 10px;
    border-radius: 50%;
}
.line {
    margin: 0 auto;
    width: 50px;
    height: 30px;
    /* border: 1px solid #000; */
    position: relative;
    top: 10px;
}
.line svg {
    width: 100%;
    height: 100%;
}
</style>
